<template>
    <view class="exam-countdown" :style="[customStyle]">
        <view
            class="u-countdown-item"
            v-if="showDays && (hideZeroDay || (!hideZeroDay && d != '00'))"
        >
            {{ d }}
        </view>
        <view
            class="exam-countdown-colon"
            v-if="showDays && (hideZeroDay || (!hideZeroDay && d != '00'))"
        >
            {{ separator == "colon" ? ":" : "天" }}
        </view>
        <view class="exam-countdown-item" v-if="showHours">
            {{ h }}
        </view>
        <view class="exam-countdown-colon" v-if="showHours">
            {{ separator == "colon" ? ":" : "时" }}
        </view>
        <view class="exam-countdown-item" v-if="showMinutes">
            {{ i }}
        </view>
        <view class="exam-countdown-colon" v-if="showMinutes">
            {{ separator == "colon" ? ":" : "分" }}
        </view>
        <view class="exam-countdown-item" v-if="showSeconds">
            {{ s }}
        </view>
        <view class="exam-countdown-colon" v-if="showSeconds">
            {{ separator == "colon" ? "" : "秒" }}
        </view>
    </view>
</template>

<script>
export default {
    name: "exam-count-down",
    props: {
        // 倒计时的时间，秒为单位
        timestamp: {
            type: [Number, String],
            default: 0,
        },
        // 是否自动开始倒计时
        autoplay: {
            type: Boolean,
            default: false,
        },
        // 用英文冒号(colon)或者中文(zh)当做分隔符，false的时候为中文，如："11:22"或"11时22秒"
        separator: {
            type: String,
            default: "colon",
        },
        // 字体颜色
        color: {
            type: String,
            default: "#303133",
        },
        // 字体大小，单位rpx
        fontSize: {
            type: [Number, String],
            default: 30,
        },
        // 是否显示秒
        showSeconds: {
            type: Boolean,
            default: true,
        },
        // 是否显示分钟
        showMinutes: {
            type: Boolean,
            default: true,
        },
        // 是否显示小时
        showHours: {
            type: Boolean,
            default: true,
        },
        // 是否显示“天”
        showDays: {
            type: Boolean,
            default: true,
        },
        // 当"天"的部分为0时，不显示
        hideZeroDay: {
            type: Boolean,
            default: false,
        },
        // 真就是倒计时，否则就是计时
        pattern: {
            type: Boolean,
            default: false,
        },
        // 用户自定义样式
        customStyle: {
            type: Object,
            default() {
                return {};
            },
        },
    },
    watch: {
        // 监听时间戳的变化
        timestamp(newVal, oldVal) {
            this.seconds = newVal;
            // 如果倒计时间发生变化，清除定时器，重新开始倒计时
            /* this.clearTimer();
            this.start(); */
        },
    },
    data() {
        return {
            d: "00", // 天的默认值
            h: "00", // 小时的默认值
            i: "00", // 分钟的默认值
            s: "00", // 秒的默认值
            timer: null, // 定时器
            seconds: 0, // 记录不停倒计过程中变化的秒数
        };
    },
    mounted() {
        // 如果自动倒计时
        this.autoplay && this.timestamp && this.start();
    },
    methods: {
        // 倒计时
        start() {
            // 避免可能出现的倒计时重叠情况
            this.clearTimer();
            // if (this.timestamp <= 0) return;
            this.seconds = Number(this.timestamp);
            this.formatTime(this.seconds);
            this.timer = setInterval(() => {
                if (this.pattern) {
                    this.seconds--;
                } else {
                    this.seconds++;
                }
                // 发出change事件
                this.$emit("change", this.seconds);
                if (this.seconds < 0) {
                    return this.end();
                }
                this.formatTime(this.seconds);
            }, 1000);
        },
        // 格式化时间
        formatTime(seconds) {
            // 小于等于0的话，结束倒计时
            seconds <= 0 && this.end();
            let [day, hour, minute, second] = [0, 0, 0, 0];
            day = Math.floor(seconds / (60 * 60 * 24));
            // 判断是否显示“天”参数，如果不显示，将天部分的值，加入到小时中
            // hour为给后面计算秒和分等用的(基于显示天的前提下计算)
            hour = Math.floor(seconds / (60 * 60)) - day * 24;
            // showHour为需要显示的小时
            let showHour = null;
            if (this.showDays) {
                showHour = hour;
            } else {
                // 如果不显示天数，将“天”部分的时间折算到小时中去
                showHour = Math.floor(seconds / (60 * 60));
            }
            minute = Math.floor(seconds / 60) - hour * 60 - day * 24 * 60;
            second =
                Math.floor(seconds) -
                day * 24 * 60 * 60 -
                hour * 60 * 60 -
                minute * 60;
            // 如果小于10，在前面补上一个"0"
            showHour = showHour < 10 ? "0" + showHour : showHour;
            minute = minute < 10 ? "0" + minute : minute;
            second = second < 10 ? "0" + second : second;
            day = day < 10 ? "0" + day : day;
            this.d = day;
            this.h = showHour;
            this.i = minute;
            this.s = second;
        },
        // 停止倒计时
        end() {
            this.clearTimer();
            if (this.pattern) {
                this.$emit("end", {});
            }
        },
        // 暂停
        pause() {
            this.clearTimer();
        },
        // 清除定时器
        clearTimer() {
            if (this.timer) {
                // 清除定时器
                clearInterval(this.timer);
                this.timer = null;
            }
        },
    },
    beforeDestroy() {
        clearInterval(this.timer);
        this.timer = null;
    },
};
</script>

<style scoped lang="scss">
.exam-countdown {
    display: flex;
    align-items: center;
}

.exam-countdown-item {
    padding: 2rpx;
}

.exam-countdown-colon {
    padding: 0 5rpx;
    line-height: 1;
    padding-bottom: 4rpx;
}
</style>
